<template>
  <div class="lazy-image" :style="{ paddingBottom: `${aspectRatio}%` }">
    <img
      v-if="isVisible || loaded"
      :src="src"
      :alt="alt"
      @load="onImageLoaded"
      :class="{ 'is-loaded': loaded }"
    />
    <div v-if="!loaded" class="image-placeholder"></div>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';

const props = defineProps({
  src: {
    type: String,
    required: true
  },
  alt: {
    type: String,
    default: ''
  },
  aspectRatio: {
    type: Number,
    default: 75 // 默认4:3比例 (75%)
  }
});

const emit = defineEmits(['loaded']);

const loaded = ref(false);
const isVisible = ref(false);
const observer = ref(null);
const imageRef = ref(null);

const onImageLoaded = (event) => {
  loaded.value = true;
  emit('loaded', {
    width: event.target.naturalWidth,
    height: event.target.naturalHeight
  });
};

onMounted(() => {
  // 使用IntersectionObserver实现懒加载
  observer.value = new IntersectionObserver((entries) => {
    if (entries[0].isIntersecting) {
      isVisible.value = true;
      observer.value.disconnect();
    }
  });
  
  if (imageRef.value) {
    observer.value.observe(imageRef.value);
  }
});

onBeforeUnmount(() => {
  if (observer.value) {
    observer.value.disconnect();
  }
});
</script>

<style scoped>
.lazy-image {
  position: relative;
  width: 100%;
  overflow: hidden;
  background-color: #f5f5f5;
}

img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.3s;
}

img.is-loaded {
  opacity: 1;
}

.image-placeholder {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, #f0f0f0 0%, #f8f8f8 50%, #f0f0f0 100%);
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
}

@keyframes shimmer {
  0% {
    background-position: -200% 0;
  }
  100% {
    background-position: 200% 0;
  }
}
</style>